/* All you need to remember is that STL containers are smart,
   but they're not smart enough to know whether to delete the
   pointers they contain. To avoid resource leaks when you have
   containers of pointers that should be deleted, you must
   either replace the pointers with smart reference-counting
   pointer objects(such as Boost's smart_ptr) or you must
   manually delete each pointer in the container before the
   container is destroyed.*/
#include <vector>
#include <algorithm>	// for for_each
#include <functional>	// For unary_function

using namespace std;

struct Widget {

};

#if 1
template<typename T>
struct DeleteObject : public unary_function<const T *, void> {
	void operator()(const T *ptr) const {
		delete ptr;
	}
};
#else
struct DeleteObject {
	template<typename T>
	void operator()(const T *ptr) const {
		delete ptr;
	}
};
#endif

void
do_something()
{
	vector<Widget *> vwp;

	/* Each of vwp's elements is destroyed when vwp
	   out of scope, but that doesn't change the fact
	   that the delete was never used for the objects
	   conjured up with new, such deletion is your
	   resposibility, not that of your vector.  */
	for (int i = 0; i < 100; ++i) {
		vwp.push_back(new Widget);
	}

	/* Making it happen seems easy enough */
	for (vector<Widget *>::iterator i = vwp.begin();
		i != vwp.end();
		++i) {
		delete *i;
	}

	/* The new for loop does pretty much what fffor_each does,
	   but it's not as clear as using for_each; Another problem
	   is that the code isn't exception safe. If an exception is
	   thrown between the time vwp is filled with pointers and
	   the time you get around to deleting them, you've leaked
	   resources again... */
#if 1
	for_each(vwp.begin(), vwp.end(), DeleteObject<Widget>());
#else
	/* ah! well-defined behavior! */
	for_each(vwp.begin(), vwp.end(), DeleteObject());
#endif

	/* But still not exception-safe. If an exception is thrown after
	 * the objects are newed but before invocation of the call to for_each,
	 * it's Leakapalooza, the simplest way is probably to replace the
	 * container of pointers with a container of smart pointers, typically
	 * reference-counted pointers.
	 * The STL itself contains no reference-counting smart pointer, and
	 * writing a good one. With boost's share_ptr, the example can be
	 * written as follows:
	 */

#if 0
	typedef boost::share_ptr<Widget> SPW;
	vector<SPW> vwp;
	for (int i = 0; i < 100; ++i) {
		/* Create a SPW from a Widget*, then
		   do a push_back on it */
		vwp.push_back(SPW new Widget);
	}
	/* No Widgets are leaked here, not even if an exception is 
	   thrown in the code above */
#endif
}

int main()
{
	do_something();	
}
